#ifndef __KERNAL_MEMORY_H
#define __KERNAL_MEMORY_H

#include"global.h"
#include"bitmap.h"
#include"list.h"

#define PG_SIZE 4096
#define PHY_BITMAP_BASE 0xc009a000
#define MEM_SIZE *((uint32_t*)0x542)

#define PG_P_0		0<<0
#define PG_P_1		1<<0
//Page can only read
#define PG_RW_R		0<<1
//Page can read write
#define PG_RW_W		1<<1
//Page can only be access by system
#define PG_US_S		0<<2
//Page can be access by all
#define PG_US_U		1<<2
//0xc0000000~0xc0100000 is kernal space
#define KERNAL_HEAP_START 0xc0100000

typedef enum{
	PG_K,
	PG_U
}p_type;

typedef struct{
	bitmap vaddr_bitmap;
	uint32_t vaddr_start;
}virtual_addr_pool;

typedef struct{
	bitmap paddr_bitmap;
	uint32_t paddr_start;
	uint32_t pool_size;
}physical_addr_pool;

//memory block only has tag take 8 bytes
typedef struct{
	list_elem b_tag;
}mem_block;

//block_size is the size of memory block it take
typedef struct{
	uint32_t block_size;
	uint32_t block_count_per_arena;
	list free_block_list;	
}mem_block_des;

//memory arena take memory block
typedef struct{
	uint32_t free_block_count;
	mem_block_des* block_des;
	bool large;
}mm_meta;

//bank hold the 7 memory block discriptor size from 16~1024 bytes
typedef struct{
	mem_block_des mem_block_des_vec[7];
}mem_bank;

void mem_init(void);

void mem_bank_init(mem_bank*);

void pfree(p_type,uint32_t,uint32_t);
//alloc pages memory for thread
void* get_page(p_type,uint32_t);

void free_page(p_type,void*,uint32_t);

void* get_fix_vpage(p_type,uint32_t);

void* get_fix_clone_vpage(p_type,uint32_t);

void* vaddr2paddr(uint32_t);

void* pde_ptr(uint32_t);

void* pte_ptr(uint32_t);

void* sys_malloc(uint32_t size);

void sys_free(void* addr);

#endif
